//
//  main.c
//  ChainStack
//
//  Created by Shawn Li on 2020/4/14.
//  Copyright © 2020 Shawn. All rights reserved.
//

#include "stdio.h"
#include "stdlib.h"
#include "time.h"
#include "math.h"

#define MAXSIZE 20
#define SUCCESS 1
#define ERROR 0
#define TRUE 1
#define FLASE 0

typedef int ElementType;
typedef int Status;

//定义了一个堆栈的结点。同时定义了指向该类结点的指针类型。
typedef struct StackNode{
    ElementType data;
    struct StackNode *next;
}StackNode, *StackNodePtr;

typedef struct ChainStack{
    StackNodePtr top;
    int count;
}ChainStack;


/// 初始化堆栈
/// @param s 堆栈
Status stackInit(ChainStack *s){
    s->top = NULL;
    s->count = 0;
    return SUCCESS;
}


/// 清空堆栈 清空堆栈的时候需要将栈内的结点都释放掉。
/// @param s 堆栈
Status stackClear(ChainStack *s){
    StackNodePtr p, temp;
    
    p = s->top;
    while (p) {
        temp = p;
        p = p->next;
        free(temp);
    }
    s->count = 0;
    s->top = NULL;
    return SUCCESS;
}


/// 判断堆栈是否为空
/// @param s 堆栈
Status stackIsEmpty(ChainStack s){
    return 0 == s.count;
}


/// 获取堆栈的长度
/// @param s 堆栈
Status stackGetCount(ChainStack s){
    return s.count;
}


/// 遍历输出堆栈
/// @param s 堆栈
Status stackPrint(ChainStack s){
    StackNodePtr p;
    
    p = s.top;
    
    printf("链表信息：");
    while (p) {
        printf("%d, ", p->data);
        p = p->next;
    }
    printf("\n\n");
    
    return SUCCESS;;
}


/// 压栈
/// @param s 堆栈
/// @param e 入栈元素
Status stackPush(ChainStack *s, ElementType e){
    
    StackNodePtr k;
    k = (StackNodePtr)malloc(sizeof(StackNode));
    k->data = e;
    
    k->next = s->top;
    s->top = k;
    s->count++;
    
    return SUCCESS;
}


/// 弹栈
/// @param s 堆栈
/// @param e 出栈元素带回
Status stackPop(ChainStack *s, ElementType *e){
    
    if (!stackGetCount(*s)) {
        printf("堆栈已经空了！");
        return ERROR;
    }
    
    StackNodePtr k;
    
    k = s->top;
    *e = k->data;
    s->top = s->top->next;
    free(k);
    
    return SUCCESS;
}


int main(int argc, const char *argv[]){
    printf("Hello world.");
    
    ChainStack s;
    ElementType e;
    
    stackInit(&s);
    stackPrint(s);
    
    for (int i = 0; i < 10; i++) {
        stackPush(&s, i);
        stackPrint(s);
    }
    
    for (int i = 0; i < 10; i++) {
        stackPop(&s, &e);
        printf("出栈元素值为：%d ,", e);
        stackPrint(s);
    }
    
    return 1;
}
